package Busquedas;

import Problemas.Problema;
import java.util.ArrayList;

/**
 * Clase para implementar la busqueda de primero en profundidad.
 * Extiende de la clase Busqueda.
 
 */
public class PrimeroProfundidad extends Busqueda {
	

	public PrimeroProfundidad(Problema p){
		super(p);		
	} 
	
	/* (non-Javadoc)
	 * @see Busqueda#buscar(boolean)
	 */
	public ArrayList<Estado> buscar(boolean controlCiclos){
		abiertos.add(this.getNodo()); //se añade la raíz
		expandidos.add(this.getNodo().getEstado());
		Nodo n;
		int op=0;
		long tiempo1=System.currentTimeMillis();
		try{	
			while(!abiertos.isEmpty()){
				contadorNodos++;
				if (contadorNodos>maxContadorNodos) return null;
				n = abiertos.get(abiertos.size()-1);			
				if (!this.getProblema().estadoFinal(n.getEstado())){
					if (op==this.getProblema().getnumOper()){
						abiertos.remove(abiertos.size()-1);
						n=n.getPadre();
						op=0;
						
					}else if (n.getOperadoresAplicados()[op]==1){
						op++;
					}else {
                        if (op==2)
                        {
                        int x=0;
                        }
						Estado e=this.getProblema().aplicaOperador(n.getEstado(), op);
						n.setOperadoresAplicados(op);
						if (e!=null){
							if (!(controlCiclos && estaEnExpandidos(e))){
								Nodo n2=n.anadeHijo(op,e,this.getProblema().getCosteOperador(op));
								abiertos.add(n2);
								expandidos.add(n.getEstado());
								int inverso = this.getProblema().getOperadorInverso(op);
								if (inverso != -1) 
									n2.setOperadoresAplicados(inverso);
								op=0;
							}
						}else {
							op++;
						}
					}
				}else{
					long tiempo2=System.currentTimeMillis();
					this.setTiempoTotal((tiempo2-tiempo1));
					generaCamino(n);
					return camino;
				}		
			}
		}catch(OutOfMemoryError e){
			abiertos = null;
			return null;
		}
		return null;
	}
	
}
